package com.jade.bss.ec.ware.impl;

import java.util.List;

import javax.ejb.TransactionAttribute;
import javax.inject.Inject;
import javax.inject.Named;

import com.jade.bss.ec.ware.*;
import com.jade.framework.base.criterion.Criteria;
import com.jade.framework.base.criterion.Order;
import com.jade.framework.base.criterion.Restrictions;
import com.jade.framework.base.util.PagingList;
import org.springframework.transaction.annotation.Transactional;

/**
 * 商品规格管理器实现。
 */
@Named ("bss_wareSpecManager")
public class SpecManagerImpl
        implements WareSpecManager
{
    private WareSpecDao specDao;

    @Inject
    public void setSpecDao(@Named ("bss_wareSpecDao") WareSpecDao specDao)
    {
        this.specDao = specDao;
    }

    @TransactionAttribute
    @Transactional (rollbackFor = Throwable.class)
    public void setSpecDefine(String ownerType, String ownerId, long cid, long wareId, int type, String name)
            throws WareException
    {
        WareSpecDefine define = getSpecDefine(ownerType, ownerId, cid, wareId, type);
        if (define == null) {
            define = new WareSpecDefine();
            define.setOwnerId(ownerId);
            define.setOwnerType(ownerType);
            define.setCid(cid);
            define.setWareId(wareId);
            define.setType(type);
        }
        define.setName(name);
        specDao.setSpecDefine(define);

    }

    public WareSpecDefine getSpecDefine(String ownerType, String ownerId, long cid, long wareId, int type)
    {
        Criteria criteria = new Criteria(0, 1);
        criteria.add(Restrictions.eq("wareId", wareId));
        criteria.add(Restrictions.eq("type", type));
        List<WareSpecDefine> defines = specDao.listSpecDefine(ownerType, ownerId, cid, criteria);
        return defines.isEmpty() ? null : defines.get(0);
    }

    public List<WareSpecDefine> listSpecDefine(String ownerType, String ownerId, long cid, long wareId)
    {
        Criteria criteria = new Criteria(-1, -1);
        criteria.add(Restrictions.eq("wareId", wareId));
        criteria.addOrder(Order.asc("sortCode"));
        return specDao.listSpecDefine(ownerType, ownerId, cid, criteria);
    }

    protected void checkSpecConflict(WareSpec spec)
            throws WareException
    {
        WareSpec old = getSpec(spec.getOwnerType(), spec.getOwnerId(), spec.getCid(), spec.getType(), spec.getWareId(),
                spec.getValue());
        if (old != null && old.getId() != spec.getId()) {
            throw new WareException("err.bss.ec.ware.spec.value_conflict", "Duplicated ware spec value",
                    null, spec.getType(), spec.getValue());
        }

    }


    @TransactionAttribute
    @Transactional (rollbackFor = Throwable.class)
    public void addSpec(WareSpec spec)
            throws WareException
    {
        checkSpecConflict(spec);
        specDao.addSpec(spec);
    }

    @TransactionAttribute
    @Transactional (rollbackFor = Throwable.class)
    public void updateSpec(WareSpec spec)
            throws WareException
    {
        checkSpecConflict(spec);
        specDao.updateSpec(spec);
    }

    @TransactionAttribute
    @Transactional (rollbackFor = Throwable.class)
    public void removeSpec(long... ids)
            throws WareException
    {
        for (long id : ids) {
            WareSpec spec = getSpec(id);
            if (spec != null) {
                specDao.removeSpec(spec);
            }
        }
    }

    protected WareSpec getSpec(String ownerType, String ownerId, long cid, int type, long wareId, String value)
    {
        Criteria criteria = new Criteria(0, 1);
        criteria.add(Restrictions.eq("wareId", wareId));
        criteria.add(Restrictions.eq("value", value));
        List<WareSpec> specs = specDao.listSpec(ownerType, ownerId, cid, type, criteria);
        return specs.isEmpty() ? null : specs.get(0);
    }

    public WareSpec getSpec(long id)
            throws WareException
    {
        return null;
    }

    public List<WareSpec> listSpec(String ownerType, String ownerId, long cid, int type)
    {
        return listSpec(ownerType, ownerId, cid, type, 0);
    }

    public List<WareSpec> listSpec(String ownerType, String ownerId, long cid, int type, int wareId)
    {
        Criteria criteria = new Criteria(-1, -1);
        criteria.add(Restrictions.eq("wareId", wareId));
        criteria.addOrder(Order.asc("sortCode"));
        return specDao.listSpec(ownerType, ownerId, cid, type, criteria);
    }

    public PagingList<WareSpec> querySpec(String ownerType, String ownerId, long cid, int type, Criteria criteria)
    {
        return specDao.querySpec(ownerType, ownerId, cid, type, criteria);
    }
}
